import { system } from "@minecraft/server";
import { modWarn } from "./message";

/**
 * Generate a random integer.
 * @param max The maximum value (inclusive). Decimals will be parsed as integers.
 * @param min The minimum value (inclusive). Decimals will be parsed as integers. Default value is 0.
 * @return A random integer between min and max (inclusive).
 * @throws RangeError if max < min
 */
export function randomInteger(max: number, min: number = 0): number {
  // Parse inputs as integers
  max = Math.ceil(max);
  min = Math.ceil(min);
  // Validate the range
  if (max < min) {
    throw new RangeError(
      `randomInteger() is used incorrectly! Expect: any number higher than ${min}. Current: ${max}`
    );
  }
  // Generate a random integer between min (inclusive) and max (inclusive)
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

/**
 * Get a random integer between 1 and 10.
 * @return A random integer between 1 and 10.
 * @deprecated Please use `randomInteger(10)` to get a random integer between 1 and 10.
 */
export function getRandomChance(): number {
  let randomChance = Math.ceil(Math.random() * 10);
  modWarn("Random chance is " + randomChance);
  return randomChance;
}

/**
 * Generate a UUID.
 * @return a UUID
 */
export function generateUUID(): string {
  const currentTimestamp: number = system.currentTick;
  return "xxxxxxxx-xxxx-4xxx-yxxx-zxxxxxxx".replace(
    /[xyz]/g,
    (args: string) => {
      const random: number = (Math.random() * 16) | 0;
      const value: number = args == "x" ? random : (random & 0x3) | 0x8;
      if (args === "z")
        return value.toString(16) + currentTimestamp.toString(16).slice(-4);
      else return value.toString(16);
    }
  );
}

/**
 * A simple function that checks if a variable is undefined or null;
 * Like Objects.requireNonNull in java.
 * @param object the object or variable to check;
 * @param message the Error message (if thrown).
 */
export function requireNonNull(object: any, message?: string) {
  if (object === undefined || object === null) {
    throw new Error(message);
  }
  return object;
}

/**
 * Ensure that namespace is present.
 * @param str
 */
export function ensureNamespace(str: string) {
  return str.includes(":") ? str : "minecraft:" + str;
}
